﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class ReglaParentesis : Regla
    {   
        //Atributos

        private int _tipo;

 
        //Propiedades

        public int Tipo
        {
            get { return _tipo; }
            set { _tipo = value; }
        }
       
        //Metodos
        public ReglaParentesis(int tipo)
        {
            //Constructor
            Tipo = tipo; 
        }

        override public Resultado Aplicar(ArrayList archivo)
        {
            try
            {
                if (Tipo == 1)
                    return regla_ParentesisCEF(archivo);
                if (Tipo == 2)
                    return regla_ParentesisSE(archivo);
                if (Tipo == 3)
                    return regla_ParentesisEx(archivo);
                if (Tipo == 4)
                    return regla_ParentesisIn(archivo);
                return null;              
            }
            catch (Exception e)
            {
                return null;
            }
        }


        public static Resultado regla_ParentesisCEF(ArrayList archivo)
        /*Valida que todos los parentesis del archivo tengan espacios antes y despues del contenido.
          Ejemplo: FuncionEjemplo ( atributos ) {             
         */
        {
            //Variables iniciales
            int AnchoLinea; //Guardara el tamaño de cada linea del archivo.
            int i = 0;      //Contador de iteraciones para los ciclos (for).
            int LineaActual = 0; //Linea actual que se esta leyendo.
            Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.

            //Inicializamos Resp asumiendo que el archivo cumple con la regla.
            Resp.Fecha = new DateTime();
            Resp.Fecha = DateTime.Now;
            Resp.Respuesta = true;
            Resp.Mensaje = "No se encontraron errores";
            Resp.Linea = 0;

            try
            {
                foreach (string linea in archivo) //Recorro la lista linea por linea
                {
                    LineaActual++;                //Aumenta el contador de la linea.
                    if (linea.Length != 0)        //Si la linea no esta vacia.
                    {
                        AnchoLinea = linea.Length;//Guardamos la cantidad de espacios de la linea.
                        i = 0;                    //Reiniciamos el contador.
                        while (i < AnchoLinea)    //Recorremos la linea caracter por caracter.
                        {
                            if (linea[i] == '(') // Si encontramos un abrir parentesis.
                            {
                                if (i == 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                                else if (linea[i - 1] != ' ') //Checkeamos que exista un espacio antes del parentesis.
                                {                        //En caso de no existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;

                                }
                                if (i + 1 > AnchoLinea) //Checkeamos que podamos preguntar por la pasicion [i+1]
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio despues de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                                else if (linea[i + 1] != ' ')
                                {
                                                          //Checkeamos que exista un espacio despues del parentesis.
                                                          //En caso de no existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio despues de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                            }
                            if (linea[i] == ')')  //Si encontramos un cerrar parentesis.
                            {
                                if (i == 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                                else if (linea[i - 1] != ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                                          //En caso de no existir llenamos el resultado con la informacion de error.

                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }

                                if (i + 1 < AnchoLinea)  //Aseguramos que se pueda preguntar por la posicion [i+1]
                                    if(linea[i + 1] != ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                                          //En caso de no existir llenamos el resultado con la informacion de error.
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio despues de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                                    
                                
                            }
                            i++;
                        }
                    }


                }

                return Resp; //Retornamos respuesta.
            }
            catch (Exception e)
            {
                Resp.Linea = LineaActual;
                Resp.Respuesta = false;
                Resp.Mensaje = "Ocurrio un error inesperado al leer la linea "+LineaActual+". Error "+e.Message;
                return Resp;                       
            }
        }

        public static Resultado regla_ParentesisSE(ArrayList archivo)
        /*Valida que todos los parentesis del archivo no tengan espacios ni antes ni despues.
          Ejemplo: FuncionEjemplo(atributos){             
         */
        {
            //Variables iniciales
            int AnchoLinea; //Guardara el tamaño de cada linea del archivo.
            int i = 0;      //Contador de iteraciones para los ciclos (for).
            int LineaActual = 0; //Linea actual que se esta leyendo.
            Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.

            //Inicializamos Resp asumiendo que el archivo cumple con la regla.
            Resp.Fecha = new DateTime();
            Resp.Fecha = DateTime.Now;
            Resp.Respuesta = true;
            Resp.Mensaje = "No se encontraron errores";
            Resp.Linea = 0;

            try
            {
                foreach (string linea in archivo) //Recorro la lista linea por linea
                {
                    LineaActual++;                //Aumenta el contador de la linea.
                    if (linea.Length != 0)        //Si la linea no esta vacia.
                    {
                        AnchoLinea = linea.Length;//Guardamos la cantidad de espacios de la linea.
                        i = 0;                    //Reiniciamos el contador.
                        while (i < AnchoLinea)    //Recorremos la linea caracter por caracter.
                        {
                            if (linea[i] == '(') // Si encontramos un abrir parentesis.
                            {
                                if (i != 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                 if (linea[i - 1] == ' ') //Checkeamos que exista un espacio antes del parentesis.
                                {                        //En caso de existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "Existe un espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;

                                }
                                if (i + 1 > AnchoLinea) //Checkeamos que podamos preguntar por la pasicion [i+1]
                                 if (linea[i + 1] == ' ')
                                {
                                    //Checkeamos que exista un espacio despues del parentesis.
                                    //En caso de existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "Existe un espacio despues de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                            }
                            if (linea[i] == ')')  //Si encontramos un cerrar parentesis.
                            {
                                if (i != 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                    if (linea[i - 1] == ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                //En caso de no existir llenamos el resultado con la informacion de error.
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "Existe un espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }

                                if (i + 1 < AnchoLinea)  //Aseguramos que se pueda preguntar por la posicion [i+1]
                                    if (linea[i + 1] == ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                    //En caso de existir llenamos el resultado con la informacion de error.
                                    {
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "Existe espacio despues de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }


                            }
                            i++;
                        }
                    }


                }

                return Resp; //Retornamos respuesta.
            }
            catch (Exception e)
            {
                Resp.Linea = LineaActual;
                Resp.Respuesta = false;
                Resp.Mensaje = "Ocurrio un error inesperado al leer la linea " + LineaActual + ". Error " + e.Message;
                return Resp;
            }
        }
        public static Resultado regla_ParentesisEx(ArrayList archivo)
        /*Valida que todos los parentesis del archivo tengan espacios en sus extremos externos.
          Ejemplo: FuncionEjemplo (atributos) {             
         */
        {
            //Variables iniciales
            int AnchoLinea; //Guardara el tamaño de cada linea del archivo.
            int i = 0;      //Contador de iteraciones para los ciclos (for).
            int LineaActual = 0; //Linea actual que se esta leyendo.
            Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.

            //Inicializamos Resp asumiendo que el archivo cumple con la regla.
            Resp.Fecha = new DateTime();
            Resp.Fecha = DateTime.Now;
            Resp.Respuesta = true;
            Resp.Mensaje = "No se encontraron errores";
            Resp.Linea = 0;

            try
            {
                foreach (string linea in archivo) //Recorro la lista linea por linea
                {
                    LineaActual++;                //Aumenta el contador de la linea.
                    if (linea.Length != 0)        //Si la linea no esta vacia.
                    {
                        AnchoLinea = linea.Length;//Guardamos la cantidad de espacios de la linea.
                        i = 0;                    //Reiniciamos el contador.
                        while (i < AnchoLinea)    //Recorremos la linea caracter por caracter.
                        {
                            if (linea[i] == '(') // Si encontramos un abrir parentesis.
                            {
                                if (i == 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }
                                else if (linea[i - 1] != ' ') //Checkeamos que exista un espacio antes del parentesis.
                                {                        //En caso de no existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "No existe espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;

                                }
                                if (i + 1 < AnchoLinea) //Checkeamos que podamos preguntar por la pasicion [i+1]
                                    if (linea[i + 1] == ' ')
                                    {
                                        //Checkeamos que exista un espacio despues del parentesis.
                                        //En caso de existir llenamos el resultado con la informacion de error.
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "Existe un espacio despues de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }
                            }
                            if (linea[i] == ')')  //Si encontramos un cerrar parentesis.
                            {
                                if (i == 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                 if (linea[i - 1] != ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                //En caso de no existir llenamos el resultado con la informacion de error.
                                {
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "Existe un espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;
                                }

                                if (i + 1 < AnchoLinea)  //Aseguramos que se pueda preguntar por la posicion [i+1]
                                    if (linea[i + 1] != ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                    //En caso de existir llenamos el resultado con la informacion de error.
                                    {
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "No existe espacio despues de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }


                            }
                            i++;
                        }
                    }


                }

                return Resp; //Retornamos respuesta.
            }
            catch (Exception e)
            {
                Resp.Linea = LineaActual;
                Resp.Respuesta = false;
                Resp.Mensaje = "Ocurrio un error inesperado al leer la linea " + LineaActual + ". Error " + e.Message;
                return Resp;
            }
        }

        public static Resultado regla_ParentesisIn(ArrayList archivo)
        /*Valida que todos los parentesis del archivo tengan espacios en sus extremos internos.
          Ejemplo: FuncionEjemplo( atributos ){             
         */
        {
            //Variables iniciales
            int AnchoLinea; //Guardara el tamaño de cada linea del archivo.
            int i = 0;      //Contador de iteraciones para los ciclos (for).
            int LineaActual = 0; //Linea actual que se esta leyendo.
            Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.

            //Inicializamos Resp asumiendo que el archivo cumple con la regla.
            Resp.Fecha = new DateTime();
            Resp.Fecha = DateTime.Now;
            Resp.Respuesta = true;
            Resp.Mensaje = "No se encontraron errores";
            Resp.Linea = 0;

            try
            {
                foreach (string linea in archivo) //Recorro la lista linea por linea
                {
                    LineaActual++;                //Aumenta el contador de la linea.
                    if (linea.Length != 0)        //Si la linea no esta vacia.
                    {
                        AnchoLinea = linea.Length;//Guardamos la cantidad de espacios de la linea.
                        i = 0;                    //Reiniciamos el contador.
                        while (i < AnchoLinea)    //Recorremos la linea caracter por caracter.
                        {
                            if (linea[i] == '(') // Si encontramos un abrir parentesis.
                            {
                                if (i != 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                    if (linea[i - 1] == ' ') //Checkeamos que exista un espacio antes del parentesis.
                                {                        //En caso de no existir llenamos el resultado con la informacion de error.
                                    Resp.Linea = LineaActual;
                                    Resp.Respuesta = false;
                                    Resp.Mensaje = "Existe un espacio antes de un parantesis en la linea " + LineaActual;
                                    return Resp;

                                }
                                if (i + 1 <= AnchoLinea) //Checkeamos que podamos preguntar por la pasicion [i+1]
                                    if (linea[i + 1] != ' ')
                                    {
                                        //Checkeamos que exista un espacio despues del parentesis.
                                        //En caso de existir llenamos el resultado con la informacion de error.
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "No existe un espacio despues de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }
                            }
                            if (linea[i] == ')')  //Si encontramos un cerrar parentesis.
                            {
                                if (i != 0) //Checkeamos que podamos preguntar por la pasicion [i-1]
                                    if (linea[i - 1] != ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                    //En caso de no existir llenamos el resultado con la informacion de error.
                                    {
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "No existe un espacio antes de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }

                                if (i + 1 < AnchoLinea)  //Aseguramos que se pueda preguntar por la posicion [i+1]
                                    if (linea[i + 1] == ' ')  //Checkeamos que exista un espacio antes del parentesis.
                                    //En caso de existir llenamos el resultado con la informacion de error.
                                    {
                                        Resp.Linea = LineaActual;
                                        Resp.Respuesta = false;
                                        Resp.Mensaje = "Existe espacio despues de un parantesis en la linea " + LineaActual;
                                        return Resp;
                                    }


                            }
                            i++;
                        }
                    }


                }

                return Resp; //Retornamos respuesta.
            }
            catch (Exception e)
            {
                Resp.Linea = LineaActual;
                Resp.Respuesta = false;
                Resp.Mensaje = "Ocurrio un error inesperado al leer la linea " + LineaActual + ". Error " + e.Message;
                return Resp;
            }
        }
    }
}
